﻿using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;
using PoolGame2.Controls;

namespace PoolGame2.Game
{
    public class FreeCamera : MoveableCamera
    {

        public FreeCamera( PoolGame game ) : base(game)
        {
            cameraPosition = new Vector3(320, 120.0f, 100.0f);
            cameraReference = new Vector3(0.0f, 0.0f, 0.0f);
            cameraTarget = cameraReference + cameraPosition;
            updownRot = 0.0f;
            leftrightRot = 0.0f;
            DefaultProjection();
            UpdateViewMatrix();
        }

        public FreeCamera(PoolGame game, Vector3 cameraPosition, Vector3 cameraTarget, Vector3 cameraUpVector) : base(game)
        {
            this.cameraPosition = cameraPosition;
            this.cameraTarget = cameraTarget;
            viewMatrix = Matrix.CreateLookAt(cameraPosition, cameraTarget, cameraUpVector); 
            updownRot = 0.0f;
            leftrightRot = 0.0f;
            DefaultProjection();            
        }

        /// <summary>Turns the camera so it is facing the point provided</summary>
        /// <param name="lookAtPosition">Position the camera should be pointing to</param>
        public void LookAt(Vector3 lookAtPosition)
        {
            // Use a local variable because we can't take a reference to the value returned
            // by a property get. The ref variant is still faster than copying entire
            // matrices around.
            Vector3 cameraPosition = this.viewMatrix.Translation;
            Matrix.CreateLookAt(ref cameraPosition, ref lookAtPosition, ref up, out this.viewMatrix);
        }

        public override void UpdateCamera(GameTime gametime)
        {
        }

        public override void GameControlPerformed(List<GameControlAction> actions)
        {
            if (this.activeCamera)
            {
                foreach (GameControlAction action in actions)
                {
                    ControlActions a = action.GetAction();
                    Vector3 moveVector = Vector3.Zero;
                    if (a == ControlActions.MOVE_FORWARD)
                    {
                        moveVector.Z -= GameConstants.TRANSLATION_MOVEMENT_AMOUNT;
                        this.translate(moveVector);
                    }
                    else if (a == ControlActions.MOVE_BACK)
                    {
                        moveVector.Z += GameConstants.TRANSLATION_MOVEMENT_AMOUNT;
                        this.translate(moveVector);
                    }
                    else if (a == ControlActions.STRAFE_LEFT)
                    {
                        moveVector.X -= GameConstants.TRANSLATION_MOVEMENT_AMOUNT;
                        this.translate(moveVector);
                    }
                    else if (a == ControlActions.STRAFE_RIGHT)
                    {
                        moveVector.X += GameConstants.TRANSLATION_MOVEMENT_AMOUNT;
                        this.translate(moveVector);
                    }
                    else if (a == ControlActions.ANALOG2_MOVE)
                    {
                        float x = (float)action.GetProperty(GameConstants.X_CHANGE) * GameConstants.CAMERA_MOVEMENT_SCALE;
                        float y = (float)action.GetProperty(GameConstants.Y_CHANGE) * GameConstants.CAMERA_MOVEMENT_SCALE;
                        this.rotate(new Vector3(x, y, 0));
                    }
                    this.UpdateViewMatrix();
                }
            }
        }

    }
}